package de.pmg_grandma;

import interfaces.AbstractWish;
import java.util.Timer;
import java.util.TimerTask;
import database.DatabaseBot;
import enums.State;
import enums.WishType;
import model.Model;
import model.WishFactory;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.graphics.Color;
import android.media.RingtoneManager;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.TextView;

public class AliveService extends Service {

	private static String TAG = AliveService.class.getSimpleName();
	public static final String GranniTitelWach = "Granni ist wach.";
	public static final String GranniTitelWunsch = "Grann hat einen Wunsch";
	public static String ACTION_BROADCAST =	"de.pmg-grandma.intent.action.BROADCAST";
	private long mStartTime; //Zeit seit Beginn des Spiels
	private Timer mTimer;
	private final IBinder mBinder = new LocalBinder();


	//Zum prueffen, ob gameOverAct schon aufgerufen wurde
	public boolean gameOverActivity = false;


	private AliveService thisService;


	// Schnittstellenmethoden für den Service
	public class LocalBinder extends Binder {
		AliveService getService() {
			return AliveService.this;
		}
	}
	@Override
	public IBinder onBind(Intent intent) {
		return mBinder;
	}



	//action die alle 5000ms aufgerufen wird. Hier wird ein Broadcast gesendet
	private TimerTask mTimerTaskWishCloud = new TimerTask() {
		@Override
		public void run() {
			long now = System.currentTimeMillis();
			final Intent broadcastIntent =	new Intent(ACTION_BROADCAST);
			broadcastIntent.putExtra("wishCloud", (String.valueOf((int) ((now - mStartTime) / 1000))));
			getApplicationContext().sendBroadcast(broadcastIntent);
		}
	};
	//action die alle 1000ms aufgerufen wird. Hier wird ein Broadcast gesendet
	private TimerTask mTimerTask = new TimerTask() {
		@Override
		public void run() {
			long now = System.currentTimeMillis();
			final Intent broadcastIntent =	new Intent(ACTION_BROADCAST);
			broadcastIntent.putExtra("zaehler", (String.valueOf((int) ((now - mStartTime) / 1000))));
			broadcastIntent.putExtra("isAlive", Model.getInstance().grandmaIsAlive());

			//Wenn Oma tot --> MainActivity schliessen und als Popup GameOverActivity
			if(!Model.getInstance().grandmaIsAlive()){

				//Wenn gameOverAct noch nicht aufgerufen wurde
				if(!gameOverActivity){
					Intent intent = new Intent(thisService, GameOverActivity.class);
					intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

					//Resete Model und Datenbank
					Model.destroyInstance();
					DatabaseBot.getBot(thisService).resetDatabase();

					//Starte GameOverAct
					thisService.startActivity(intent);
					MainActivity.mainActivity.finish();

					gameOverActivity = true;
				}

			}

			long tempTime = DatabaseBot.getBot(thisService).getWakeUpTime();

			//App hat den Fokus UND Zeit aufzuwachen
			//ODER
			//Lese aus Datenbank, ob Zeit zum Aufwachen ist
			if(MainActivity.mainActivity != null && Model.getInstance().isTimeToWakeUp(now) || (tempTime != 0 && now >= tempTime)) {
				broadcastIntent.putExtra("wakeUp", true);
				Model.getInstance().wakeUp();

				//Wenn App nicht den Fokus hat --> generiere Benachrichtigung
				if(!Model.getInstance().inAppFocus)
					makeNotification(getResources().getString(R.string.nm_guten_morgen), GranniTitelWach);

				//Lösche Aufwachzeit aus Datenbank
				DatabaseBot.getBot(thisService).eraseWakeUpTime();
			}

			getApplicationContext().sendBroadcast(broadcastIntent);
		}
	};
	//##############Essenswunsch#################
	private TimerTask mTimerTaskFood = new TimerTask() {
		@Override
		public void run() {

			//Wenn MainAct nicht den Fokus hat ODER irgendein Essenswunsch noch nicht in der Datenbank existiert
			if(MainActivity.mainActivity != null || !DatabaseBot.getBot(thisService).existWishInDB(WishType.WishToEat)){

				//Wenn Oma wach ist
				if (Model.getInstance().getState() == State.Awake) {
					AbstractWish wish=null;
					long now = System.currentTimeMillis();
					final Intent broadcastIntent =	new Intent(ACTION_BROADCAST);

					//Wenn Zeit zu einem bestimmten Essen ist (breakfast,Lunch,Dinner) --> generiere einen zufälligen Essenswunsch
					if (Model.isTimeForBreakfast(now) || Model.isTimeForLunch(now) || Model.isTimeForDinner(now)) {
						wish = WishFactory.createWishToEat();

					}
					if (wish != null) {
						broadcastIntent.putExtra("Wunsch", wish.getType().name());

						//Hat App keinen Fokus --> Generiere Benachrichtigung
						if(!Model.getInstance().inAppFocus)
							makeNotification(getResources().getString(R.string.nm_hunger), GranniTitelWunsch);
						getApplicationContext().sendBroadcast(broadcastIntent);

					}
				}
			}
		}
	};

	//##############Trinkwunsch#################
	private TimerTask mTimerTaskDrink = new TimerTask() {
		@Override
		public void run() {

			//Wenn MainAct nicht den Fokus hat ODER der Trinken-wunsch noch nicht in der Datenbank existiert
			if(MainActivity.mainActivity != null || !DatabaseBot.getBot(thisService).existWishInDB(WishType.WishToDrink)){
				AbstractWish wish=null;

				//Wenn Oma wach ist
				if (Model.getInstance().getState() == State.Awake) {
					final Intent broadcastIntent =	new Intent(ACTION_BROADCAST);

					wish = WishFactory.createWishToDrink();

					if (wish != null) {
						broadcastIntent.putExtra("Wunsch", wish.getType().name());

						//Hat App keinen Fokus --> Generiere Benachrichtigung
						if(!Model.getInstance().inAppFocus)
							makeNotification(getResources().getString(R.string.nm_durst), GranniTitelWunsch);
						getApplicationContext().sendBroadcast(broadcastIntent);
					}
				}
			}
		}
	};
	//##############Medizinwunsch#################
	private TimerTask mTimerTaskMedizin = new TimerTask() {
		@Override
		public void run() {

			//Wenn MainAct nicht den Fokus hat ODER der Medizinwunsch noch nicht in der Datenbank existiert
			if(MainActivity.mainActivity != null || !DatabaseBot.getBot(thisService).existWishInDB(WishType.WishToTakeMedicine)){
				AbstractWish wish=null;

				//Wenn Oma wach ist
				if (Model.getInstance().getState() == State.Awake) {
					long now = System.currentTimeMillis();
					final Intent broadcastIntent =	new Intent(ACTION_BROADCAST);

					//Je nach aktueller Zeit, generiere jewilligen Medizinwunsch
					if (Model.isTimeForBreakfast(now)) {
						wish = WishFactory.createWishToTakeMedicine(Model.MEDIZIN_MORGENS);
					}
					else if (Model.isTimeForDinner(now)) {
						wish = WishFactory.createWishToTakeMedicine(Model.MEDIZIN_ABENDS);
					}
					if(wish != null) {
						broadcastIntent.putExtra("Wunsch", wish.getType().name());

						//Hat App keinen Fokus --> Generiere Benachrichtigung
						if(!Model.getInstance().inAppFocus)
							makeNotification(getResources().getString(R.string.nm_medizin), GranniTitelWunsch);
						getApplicationContext().sendBroadcast(broadcastIntent);
					}
				}
			}
		}
	};
	//##############Schlafenwunsch#################
	private TimerTask mTimerTaskSleep = new TimerTask() {
		@Override
		public void run() {

			//Wenn MainAct nicht den Fokus hat ODER der Schlafenswunsch noch nicht in der Datenbank existiert
			if(MainActivity.mainActivity != null || !DatabaseBot.getBot(thisService).existWishInDB(WishType.WishToSleep)){
				AbstractWish wish=null;

				//Wenn Oma wach ist
				if (Model.getInstance().getState() == State.Awake) {
					long now = System.currentTimeMillis();
					final Intent broadcastIntent =	new Intent(ACTION_BROADCAST);

					//Wenn gerade Schlafenszeit ist --> Lass sie richtig schlafen (9 Stunden)
					if (Model.isTimeToSleep(now)) {
						wish = WishFactory.createWishToSleep(Model.SCHLAFEN_LANG);
					}
					if (wish != null) {
						broadcastIntent.putExtra("Wunsch", wish.getType().name());

						//Hat App keinen Fokus --> Generiere Benachrichtigung
						if(!Model.getInstance().inAppFocus)
							makeNotification(getResources().getString(R.string.nm_schlafen), GranniTitelWunsch);
						getApplicationContext().sendBroadcast(broadcastIntent);
					}
				}
			}
		}
	};

	//##############Putzenwunsch#################
	private TimerTask mTimerTaskCleanApartment = new TimerTask() {
		@Override
		public void run() {
			AbstractWish wish = null;

			//Wenn Oma wach ist
			if (Model.getInstance().getState() == State.Awake) {
				long now = System.currentTimeMillis();
				final Intent broadcastIntent =	new Intent(ACTION_BROADCAST);

				//Wenn Zeitpunkt zum Putzen jetzt ist --> Generiere Putzwunsch
				if (Model.isTimeToCleanApartment(now)) {
					wish = WishFactory.createWishToCleanApartment();
				}
				if (wish != null) {
					broadcastIntent.putExtra("Wunsch", wish.getType().name());
					
					//Hat App keinen Fokus --> Generiere Benachrichtigung
					if(!Model.getInstance().inAppFocus)
						makeNotification(getResources().getString(R.string.nm_putzen), GranniTitelWunsch);
					getApplicationContext().sendBroadcast(broadcastIntent);
				}
			}
		}
	};


	@Override
	public void onCreate() {
		super.onCreate();

		Log.d(TAG, "AliveService onCreate");
		mTimer = new Timer();	//Timer starten

		thisService = this;
	}
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.d(TAG, "AliveService onStartCommand");

		mTimer.scheduleAtFixedRate(mTimerTaskWishCloud , 0, 5000);	//Timer: ruft mTimerTask alle 5s
		mTimer.scheduleAtFixedRate(mTimerTask , 0, 1000);	//Timer: ruft mTimerTask alle 1s

		mTimer.scheduleAtFixedRate(mTimerTaskFood, Model.ZEIT_SEKUNDE * 5, Model.ZEIT_MINUTE * 45); //TimerTask fuer Essen
		mTimer.scheduleAtFixedRate(mTimerTaskDrink, Model.ZEIT_SEKUNDE * 5, Model.ZEIT_SEKUNDE * 20);	//TimerTask fuer Trinken
		mTimer.scheduleAtFixedRate(mTimerTaskMedizin, Model.ZEIT_SEKUNDE * 5, Model.ZEIT_MINUTE * 35);	//TimerTask fuer Medizin
		mTimer.scheduleAtFixedRate(mTimerTaskSleep, Model.ZEIT_SEKUNDE * 5, Model.ZEIT_MINUTE * 30);	//TimerTask fuer Schlafen
		mTimer.scheduleAtFixedRate(mTimerTaskCleanApartment, Model.ZEIT_SEKUNDE * 5, Model.ZEIT_MINUTE * 50);	//TimerTask fuers Putzen

		return START_STICKY;
	}
	@Override
	public void onDestroy() {
		Log.d(TAG, "AliveService onDestroy");
		mTimer.cancel();	//Timer anhalten
		super.onDestroy();
	}

	public void makeNotification(String wunsch, String titelanzeige)
	{
		if(!Model.getInstance().inAppFocus) {
			//Notification-Manager holen
			NotificationManager notificationManager = (NotificationManager) this.getSystemService(this.NOTIFICATION_SERVICE);
			
			//Neue Notification erstellen mit Symbol, Titel und der Zeit
			Notification notification = new Notification(R.drawable.ic_launcher, wunsch, System.currentTimeMillis());
			//Flag für das Reagieren beim Klicken auf die Notification
			notification.flags |= Notification.FLAG_AUTO_CANCEL;
			
			//Feineinstellungen -> Vibration, Sound und Licht
			notification.vibrate = new long[] { 100, 250, 100, 500};
			notification.sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
			notification.defaults = 1;
			notification.ledARGB = Color.MAGENTA;
			notification.ledOnMS = 1000;
			notification.ledOffMS = 300;
			//Inhalt der Notification mit Textinhalt
			RemoteViews tempViews = new RemoteViews(this.getPackageName(),R.layout.mylist);
			TextView notificationTextView = new TextView(this);
			//Texteinstellungen und Text setzen
			tempViews.setTextColor(Model.getInstance().getNotificationCount(), Color.BLACK);
			tempViews.setTextViewText(Model.getInstance().getNotificationCount(), wunsch);
			notification.contentView = tempViews;
			
			//neues PendigIntent
			PendingIntent pendingIntent;
			//Wenn die MainActivity vorhanden ist, nutze diesen als Intent um den Intent zu starten
			//wenn man auf die Notification draufklickt
			if(MainActivity.mainActivity != null) {
				pendingIntent = PendingIntent.getActivity(this, 0, MainActivity.mainActivity.getIntent(), 0);
			}
			//wenn MainActivity nicht vorhanden, dann erstelle eine neues Intent
			else {
				pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
			}
		
			//setzen des Intents
			notification.contentIntent = pendingIntent;
			notification.setLatestEventInfo(this, titelanzeige, wunsch, pendingIntent);
			
			notificationManager.notify(Model.getInstance().getNotificationCount(), notification);
			notification.number = Model.getInstance().addNotificationCount();

			//Email-Service, neues Intent, die die Email versendet
			DatabaseBot tempBot = DatabaseBot.getBot(this);
			if(tempBot.getEmailService()) {
				Intent emailIntent = new Intent(this,EmailActivity.class);
				emailIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				emailIntent.putExtra("Wunsch", wunsch);
				emailIntent.putExtra("Titel", titelanzeige);
				startActivity(emailIntent);
			}
		}
	}
}
